package com.ean.backpack.security;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ean.backpack.domain.User;
import com.ean.backpack.repository.UserRepository;

/**
 *
 * An implementation of Spring Security's UserDetailsService.
 *
 * @author valentin
 *
 */
@Service("authenticationService")
public class AuthenticationService implements UserDetailsService {

	private static final Logger logger = Logger
			.getLogger(AuthenticationService.class);

	@Autowired
	private UserRepository userRepository;

	@Override
	@Transactional
	public UserDetails loadUserByUsername(String email)
			throws UsernameNotFoundException, DataAccessException {
		if ((email == null) || email.trim().isEmpty()) {
			throw new UsernameNotFoundException("Email is null or empty");
		}

		logger.debug("Checking  users with email: " + email);
		User user = userRepository.findByEmail(email);

		if (user == null) {
			String errorMsg = "User with email: " + email
					+ " could not be found";
			logger.debug(errorMsg);
			throw new UsernameNotFoundException(errorMsg);
		}

		Collection<GrantedAuthority> grantedAuthorities = toGrantedAuthorities(user
				.getRoleNames());
		String password = user.getPassword();
		boolean enabled = user.getIsEnabled();
		boolean userNonExpired = true;
		boolean credentialsNonExpired = true;
		boolean userNonLocked = true;

		return new org.springframework.security.core.userdetails.User(email,
				password, enabled, userNonExpired, credentialsNonExpired,
				userNonLocked, grantedAuthorities);
	}

	public static Collection<GrantedAuthority> toGrantedAuthorities(
			List<String> roles) {
		List<GrantedAuthority> result = new ArrayList<GrantedAuthority>();

		for (String role : roles) {
			result.add(new SimpleGrantedAuthority(role));
		}

		return result;
	}
}
